#include "fw/include/mgos_sys_config.h"
#include "fw/include/mgos_timers.h"
#include "fw/include/mgos.h"
#include "fw/include/mgos_app.h"
#include "fw/include/mgos_mongoose.h"
#include "fw/include/mgos_uart.h"
#include "fw/include/mgos_gpio.h"
#include "common/cs_dbg.h"
#include "common/platform.h"
#include "frozen/frozen.h"
#include "sht1x_v3.h"
#include "queue.h"
#include "relay.h"
#include "myconfig.h"
#include "mgos_wifi.h"
#include "mymqtt.h"
#include "ds18b20.h"
//#inlude "PID_v1.h"

#define UART_NO 0
#define led_0 16
#define btn_set 4
#define btn_reset 5

//sensor type
enum SENSOR_TYPE
{
  sht1x = 0,
  ds18b20
} sensor_type;

//const struct sys_config_wifi_sta *ap;
static char mode_temp = 0x3;
static char mode_hum = 0x5;
static bool wifi_is_connected = false;
static bool is_ap = false;
static Queue *log_data; // log t and h

// 继电器
static struct Relay relay_0 = {0, 16, false, false, false, false, false, 0, 0, 0, 0, {0}}; //D0
static struct Relay relay_1 = {1, 14, false, false, false, false, false, 0, 0, 0, 0, {0}}; //D5
static struct Relay relay_2 = {2, 12, false, false, false, false, false, 0, 0, 0, 0, {0}}; //D6
static struct Relay *p_relays[] = {&relay_0, &relay_1, &relay_2};

static int c = 0;
static bool say_hi = true;

//temp, humidy
static float t = 0, h = 0;

//取t,h
static void get_th(void)
{
  //which sensor
  switch (sensor_type)
  {
  case ds18b20:
    t = get_ds18b20();
    break;
  case sht1x:
  {
    SHT1x_V3 sht1x = get_sht1x();
    t = sht1x.t_true;
    h = sht1x.h_true;
    break;
  }
  }
}

//按键
static void cb_btn(int pin, void *arg)
{
  //printf("button set \n");
  if (pin == btn_set)
  {
    const struct mgos_config_wifi_ap *cfg_ap = mgos_sys_config_get_wifi_ap();
    const struct mgos_config_wifi_sta *cfg_sta = mgos_sys_config_get_wifi_sta();

    if (!is_ap)
    {
      // if sta connect, disconect
      mgos_wifi_disconnect();
      mgos_sys_config_set_wifi_sta_enable(false);
      mgos_wifi_setup_sta(cfg_sta);

      printf("enter mode: ap \n");

      mgos_sys_config_set_wifi_ap_enable(true);
      mgos_wifi_setup_ap(cfg_ap);
      is_ap = true;
    }
    else
    {
      mgos_sys_config_set_wifi_ap_enable(false);
      mgos_wifi_setup_ap(cfg_ap);
      is_ap = false;
      printf("enter mode: sta \n\n");
      mgos_sys_config_set_wifi_sta_enable(true);
      mgos_wifi_setup_sta(cfg_sta);
    }
  }
  (void)arg;
}

//心跳信号
static void cb_led_heartbeat(void *arg)
{
  //mgos_gpio_toggle(led_0);
  //printf("Hi, I am here,...\n");
  (void)arg;
}

//读sht1x
static void cb_read_sht1x(void *arg)
{
  measure(*(char *)arg);
}
//读ds18b20
static void cb_read_ds18b20(void *arg)
{
  read_ds18b20();
  (void)arg;
}
//发布mqtt温湿度数据
static void cb_mqtt_push_th(void *arg)
{
  if (wifi_is_connected)
  {
    struct mg_connection *con = mgos_mqtt_get_global_conn();
    //read th, 所有1次
    get_th();
    //mqtt pub
    if (con != NULL)
    {
      pub(con, "{t:%f, h:%f}", t, h);
    }
    else
    {
      printf("No mqtt conn.\n");
    }

    //outer if
  }
  (void)arg;
}

//wifi状态变化
static void cb_wifi_state_change(enum mgos_wifi_status event, void *arg)
{
  if (event == 2)
  {
    printf("ip acquired.\n");
    wifi_is_connected = true;
  }
  (void)arg;
}
//wifi定时检查状态
static void cb_wifi_conect(void *arg)
{
  enum mgos_wifi_status wifi_status = mgos_wifi_get_status();
  if (wifi_status == 0)
  {
    mgos_wifi_connect();
    wifi_is_connected = false;
    printf("connect wifi, once 30s ...\n");
  }
  (void)arg;
}

static void cb_process(void *arg)
{
  c++;
  if (c >= 9)
  {
    c = 0;
    //更新info
    info_update(t, h);
    //hi
    if (say_hi)
    {
      char msg[] = "Hello, I am here :)";
      say_hi = !hi(msg);
    }
  }
  r_scan(&relay_0);
  r_scan(&relay_1);
  r_scan(&relay_2);
  (void)arg;
}

/* main entry */
enum mgos_app_init_result mgos_app_init(void)
{
  //init config
  //mgos_sys_config_init();
  //sta mode
  const struct mgos_config_wifi_sta *cfg_sta = mgos_sys_config_get_wifi_sta();
  mgos_sys_config_set_wifi_sta_enable(true);
  mgos_wifi_setup_sta(cfg_sta);

  // 队列
  log_data = CreateQueue(96);

  // 注册按键
  mgos_gpio_set_button_handler(btn_set, MGOS_GPIO_PULL_UP, MGOS_GPIO_INT_EDGE_POS, 1000, cb_btn, NULL);
  mgos_gpio_set_button_handler(btn_reset, MGOS_GPIO_PULL_UP, MGOS_GPIO_INT_EDGE_POS, 500, cb_btn, NULL);

  // heartbeat
  mgos_gpio_set_mode(led_0, MGOS_GPIO_MODE_OUTPUT);
  mgos_set_timer(2 * 1000, true, cb_led_heartbeat, NULL);

  // 判断温度传感器类型
  const char *th = mgos_sys_config_get_dev_th();
  if (strcmp(th, "ds18b20") == 0)
  {
    sensor_type = ds18b20;
    // 读取温度
    init_ds18b20();
    mgos_set_timer(1 * 1000, true, cb_read_ds18b20, NULL);
    // MQTT发布
    mgos_set_timer(10 * 1000, true, cb_mqtt_push_th, NULL);
  }
  else if (strcmp(th, "sht1x") == 0)
  {
    sensor_type = sht1x;
    // sht1x读取温湿度
    connectionreset();
    mgos_set_timer(15 * 1000, true, cb_read_sht1x, &mode_temp);
    mgos_set_timer(10 * 1000, true, cb_read_sht1x, &mode_hum);
  }

  // MQTT事件处理
  mgos_mqtt_add_global_handler(evt_mqtt_handler, NULL);
  mgos_wifi_add_on_change_cb(cb_wifi_state_change, NULL);
  mgos_set_timer(30 * 1000, true, cb_wifi_conect, NULL);
  // MQTT发布
  mgos_set_timer(10 * 1000, true, cb_mqtt_push_th, NULL);

  //rpc
  //my.get
  mgos_rpc_add_handler("my.get", cb_myRpcConfig, p_relays);
  //manual on/off
  mgos_rpc_add_handler("my.manual", cb_myRpcManual, p_relays);

  // 继电器输出
  r_init(0, &relay_0);
  r_init(1, &relay_1);
  r_init(2, &relay_2);
  mgos_set_timer(100, true, cb_process, NULL);

  // 菜谱
  //double Setpoint, Input, Output;
  //Setpoint = 63.0;  // 鸡蛋
  //PID();
  // 调温, 100us分度
  //mgos_timer_id mgos_set_hw_timer(100, 1, Compute, NULL);

  return MGOS_APP_INIT_SUCCESS;
}
